var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var _a;
// 类型推导
var someValue = 'this is string';
var strLength = someValue.length;
var sv = 'this is string';
var strLength1 = someValue.length;
// 非空断言
// let flag: null | undefined | string
// flag!.toString()
// flag?.toString()
// 字面量类型
var flag2 = 'hello';
var str1 = {
    x: 1,
    y: 'hello'
};
function getNumber(value) {
    if ('fly' in value) {
        return value.fly;
    }
    return value.leg;
}
// 类型保护
var Animal = /** @class */ (function () {
    function Animal() {
    }
    return Animal;
}());
var Bird = /** @class */ (function (_super) {
    __extends(Bird, _super);
    function Bird() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return Bird;
}(Animal));
function getNumber1(animal) {
    if (animal instanceof Bird) {
        return animal.fly;
    }
    else {
        return animal.name;
    }
}
// 自定义类型保护
function isBird(value) {
    return value instanceof Bird;
}
function getNumber2(animal) {
    if (isBird(animal)) {
        console.log(animal.fly);
    }
    else {
        console.log(animal.name);
    }
}
var countNum = function (a, b) { return a + b; };
// 函数重载
var obj = {};
function attr(val) {
    if (typeof val === 'string') {
        obj.name = val;
    }
    else {
        obj.age = val;
    }
}
attr('hahaha');
attr(9);
attr(true);
console.log(obj);
var Person = /** @class */ (function () {
    function Person(name, age, car) {
        this.name = name;
        this.age = age;
        this.car = car;
    }
    Person.prototype.getName = function () {
        console.log(this.name, this.age, this.car);
    };
    return Person;
}());
var p1 = new Person('人类1', 23, 1);
p1.getName();
var Student = /** @class */ (function (_super) {
    __extends(Student, _super);
    function Student(name, age, car) {
        return _super.call(this, name, age, car) || this;
    }
    Student.prototype.getName = function () {
        console.log(this.name, this.age);
    };
    return Student;
}(Person));
var s1 = new Student('学生1', 12, 0);
s1.getName();
var SomePartialPoint = /** @class */ (function () {
    function SomePartialPoint() {
        this.x = 1;
        this.y = 2;
    }
    return SomePartialPoint;
}());
function loginTest(arg) {
    console.log(arg.length);
    return arg;
}
// typeof关键字
var obj1 = {
    name: "foo",
    age: 123,
    gender: 'male'
};
function show(p) {
    return p.name;
}
function getValueByKey(p, key) {
    return p[key];
}
var pValue = getValueByKey({ name: '张三', age: 12, gender: 'male' }, 'name');
console.log(pValue);
var pp1 = { name: '张三' };
var rq1 = {
    name: 'mk',
    age: 23,
    gender: 'female'
};
var todo1 = {
    title: 'title',
    desc: 'desc'
};
var cars = (_a = {
        x: { value: 10 },
        0: { value: 20 }
    },
    _a[Symbol('test')] = 1,
    _a);
// =================装饰器==================
var NSA;
(function (NSA) {
    // 当装饰器作为修饰类的时候，会把构造器传递进去
    function addNameEat(constructor) {
        constructor.prototype.name = 'hello';
        constructor.prototype.eat = function () {
            console.log('eat');
        };
    }
    var Person = /** @class */ (function () {
        function Person() {
        }
        Person = __decorate([
            addNameEat
        ], Person);
        return Person;
    }());
    var p = new Person();
    console.log(p.name);
    p.eat();
})(NSA || (NSA = {}));
var NSB;
(function (NSB) {
    //还可以使用装饰器工厂 这样可以传递额外参数
    function addNameEatFactory(name) {
        return function addNameEat(constructor) {
            constructor.prototype.name = name;
            constructor.prototype.eat = function () {
                console.log('eat');
            };
        };
    }
    var Person = /** @class */ (function () {
        function Person() {
        }
        Person = __decorate([
            addNameEatFactory('hello')
        ], Person);
        return Person;
    }());
    var p1 = new Person();
    console.log(p1.name);
    p1.eat();
})(NSB || (NSB = {}));
var NSC;
(function (NSC) {
    function enhancer(constructor) {
        return /** @class */ (function () {
            function class_1() {
                this.name = 'jiagou';
            }
            class_1.prototype.eat = function () {
                console.log('吃饭');
            };
            return class_1;
        }());
    }
    var Person = /** @class */ (function () {
        function Person() {
        }
        Person = __decorate([
            enhancer
        ], Person);
        return Person;
    }());
    var p = new Person();
    console.log(p.name);
    p.eat();
})(NSC || (NSC = {}));
// =======属性装饰器=======
var NSD;
(function (NSD) {
    //修饰实例属性
    function upperCase(target, propertyKey) {
        var value = target[propertyKey];
        var getter = function () {
            return value;
        };
        // 用来替换的setter
        var setter = function (newVal) {
            value = newVal.toUpperCase();
        };
        // 替换属性，先删除原先的属性，再重新定义属性
        if (delete target[propertyKey]) {
            Object.defineProperty(target, propertyKey, {
                get: getter,
                set: setter,
                enumerable: true,
                configurable: true
            });
        }
    }
    var Person = /** @class */ (function () {
        function Person() {
        }
        __decorate([
            upperCase
        ], Person.prototype, "name");
        return Person;
    }());
    var p = new Person();
    p.name = "world";
    console.log(p.name);
    // ======装饰器执行顺序======= 
    function Class1Decorator() {
        return function (target) {
            console.log("类1装饰器");
        };
    }
    function Class2Decorator() {
        return function (target) {
            console.log("类2装饰器");
        };
    }
    function MethodDecorator() {
        return function (target, methodName, descriptor) {
            console.log("方法装饰器");
        };
    }
    function MethodDecorator2() {
        return function (target, methodName, descriptor) {
            console.log("方法装饰器2");
        };
    }
    function Param1Decorator() {
        return function (target, methodName, paramIndex) {
            console.log("参数1装饰器");
        };
    }
    function Param2Decorator() {
        return function (target, methodName, paramIndex) {
            console.log("参数2装饰器");
        };
    }
    function PropertyDecorator(name) {
        return function (target, propertyName) {
            console.log(name + "属性装饰器");
        };
    }
    var Person1 = /** @class */ (function () {
        function Person1() {
            this.name = "hello";
            this.age = 10;
        }
        Person1.prototype.greet = function (p1, p2) { };
        __decorate([
            PropertyDecorator("name")
        ], Person1.prototype, "name");
        __decorate([
            PropertyDecorator("age")
        ], Person1.prototype, "age");
        __decorate([
            MethodDecorator(),
            MethodDecorator2(),
            __param(0, Param1Decorator()),
            __param(1, Param2Decorator())
        ], Person1.prototype, "greet");
        Person1 = __decorate([
            Class1Decorator(),
            Class2Decorator()
        ], Person1);
        return Person1;
    }());
})(NSD || (NSD = {}));
